﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using IndyMosaic.Models.Blog;
using IndyMosaic.Models.Web;
using IndyMosaic.Core.Data;
using IndyMosaic.Core.Extensions;
using IndyMosaic.Org.Site.ViewData.Blog;
using System.Web.Security;
using System.Text;

namespace IndyMosaic.Org.Site.Controllers
{
    public class BlogController : Controller
    {
        private IBlogRepository repository { get; set; }

        #region Contructors
        public BlogController()
            : this(new BlogRepository())
        {
        }

        public BlogController(IBlogRepository repository)
        {
            this.repository = repository;
        }
        #endregion

        public ActionResult Index(int? page)
        {
            if (page != null && page > 0)
            {
                page--;
            }
            const int pageSize = 10;
            var blogEntries = repository.ListAllEntries();
            var paginatedBlogEntries = new PaginatedList<Entry>(blogEntries, (page ?? 0), pageSize);

            return View(paginatedBlogEntries);
        }

        public ActionResult Details(int id)
        {
            Entry entry = repository.GetEntry(id);


            if (entry == null)
            {
                return View("NotFound");
            }
            else
            {
                entry.Content = entry.Content.Replace("<##MORE##>", "");
                Comment comment = new Comment();
                if (Request.IsAuthenticated)
                {
                    comment.EmailAddress = Membership.GetUser().Email;
                }
                //return View("Details", new Details(entry, comment, GetDetailComments(entry)));
                return View("Details", new Details(entry));
            }
        }

        public ActionResult Author(Guid authorUserID)
        {
            var entries = repository.ListAllByAuthor(authorUserID);
            if (Membership.GetUser().GetUserIDAsGuid() != authorUserID)
            {
                entries = entries.Where(e => e.DatePublished != null && e.DatePublished < DateTime.Now);
            }
            return View(entries);
        }

        #region Blog Entry
        //
        // GET: /Blog/Create
        [Authorize]
        public ActionResult Create()
        {
            Entry entry = new Entry();
            entry.AuthorName = UserRepository.GetUser().Profile.FullName;
            return View(entry);
        }

        //
        // POST: /Blog/Create
        [Authorize]
        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateInput(false)]
        public ActionResult Create(FormCollection collection)
        {
            Entry entry = new Entry();
            if (collection["published"] == "Publish")
            {
                entry.DatePublished = DateTime.Now;
            }
            entry.UserID = Membership.GetUser().GetUserIDAsGuid();
            try
            {
                UpdateModel(entry);
                repository.Add(entry);
                repository.Save();

                return RedirectToAction("Details", new { id = entry.ID });
            }
            catch
            {
                ModelState.AddRuleViolations(entry.GetRuleViolations());
                return View(entry);
            }
        }

        //
        // GET: /Blog/Edit/5

        [Authorize]
        public ActionResult Edit(int id)
        {
            Entry entry = repository.GetEntry(id);
            if (!ValidCreateEditAccess(entry))
            {
                return View("NotAuthorized");
            }
            if (entry == null)
            {
                return View("NotFound");
            }
            else
            {
                return View(entry);
            }
        }

        //
        // POST: /Blog/Edit/5
        [Authorize]
        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateInput(false)]
        public ActionResult Edit(int id, Entry newEntry)
        {
            Entry entry = repository.GetEntry(id);
            if (!ValidCreateEditAccess(entry))
            {
                return View("NotAuthorized");
            }
            try
            {
                //string[] allowedProperties = new[] { "Title", "AuthorName", "Content", "ImageURL" };
                //UpdateModel(entry);
                //UpdateModel(entry, allowedProperties);
                entry.AuthorName = newEntry.AuthorName;
                entry.Content = newEntry.Content;
                entry.DatePublished = newEntry.DatePublished;
                entry.ImageURL = newEntry.ImageURL;
                entry.Title = newEntry.Title;
                
                repository.Save();

                return RedirectToAction("Details", new { id = id });
            }
            catch
            {
                ModelState.AddRuleViolations(entry.GetRuleViolations());

                return View(entry);
            }
        }
        #endregion

        #region Syndication
        public ActionResult RSS()
        {
            var entries = repository.ListLatestTopNEntries(10);
            StringBuilder sb = new StringBuilder(Request.Url.ToString());
            sb.Replace("RSS", "Details/{0}");

            return Content(repository.GetFeed(entries, sb.ToString(), Url));
        }
        #endregion

        private bool ValidCreateEditAccess(Entry entry)
        {
            Guid userId = Membership.GetUser().GetUserIDAsGuid();
            return entry.UserID == userId || Roles.IsUserInRole("Administrator");
        }
    }
}
